我为什么在乎这一个A+

我知道有些人至今仍然嘲笑和鄙视我,因为我曾经说过,我在Dan Friedman的两门课程B521(程序语言理论)和B621(高级程序语言理论)都得了A+。只要提到我,他们就会拿出这个把柄来,好像我是一个只在乎分数的肤浅的人。实际上我觉得这些人只是为了鄙视而鄙视,所以他们发现貌似一个把柄,也不搞清楚Dan Friedman是谁,也不搞清楚这个A+的分量,拿着半截就开跑,抓住不放了。所以即使我没提过这分数的事情,他们一样会找到其它话题来损我。我一直都懒得回应这些人的言论,不过今天我有兴致显示一下自己的价值,所以想花点时间告诉你,这个A+到底意味着什么。

从我的人生历史里面,你应该很明显的看出来,课程,考试,分数,名校,权威,事业,成就,贡献,以至于图灵奖,诺贝尔奖,对于我来说真的什么都不是。你觉得一个在乎这些东西的人,会以优秀的成绩从清华,Cornell,Indiana三所大学退学吗?在漫长的学术生涯中,我上过许多的课程,很多最后结果都是A或者A+,也有几门课的分数低到C。因为我从来不觉得任何人有资格出题来考我,所以自上大学以来,我给自己定的标准就是“及格万岁”。我是一个非常不喜欢上课的人,我觉得普通的课堂讲座本身就是一种极其低效的教学方式,所以一旦觉得老师水平不够或者不懂教学就开始翘课,自己看书自学。所以,最后无论什么分数都不能衡量我的价值,反而有时候觉得高分是对我价值的侮辱——本来有时候老师教的,课本上的东西就不对,得高分意味着我得跟他们错得一样。然而,我为什么唯独在乎在一个非名校,“非名师”手里上的这门课程,并且愿意告诉你我在里面的成绩呢?

其实,这个分数的意义远远不止是一个A+,它涵盖的内容可能超乎你的想象。也许你可以从一个很小的例子看出它到底意味着什么。在课程进行到一半的时候,我花了一个星期的时间,独立解决了曾经困扰程序语言领域十多年的难题——CPS变换。CPS变换有什么用呢?如果你写过Node.js或者其它类似的东西,就知道所谓“call back hell”的代码样式,其本质就是程序语言专家所谓的“CPS”(continuation-passing style)。“CPS变换”就是可以自动把代码变换成那种样式的过程,它在本质上就是一个编译器。实际上有些函数式语言的编译器(比如SML),其中最重要的过程就是CPS变换。CPS变换之后,你可以掌握代码中的“控制流”,实现所谓“超轻量线程”,进而可以实现最近很流行的,所谓“大规模并发”。所以你看到了,这些很流行的概念,在程序语言专家看来,并不是什么稀奇的东西,甚至不是新的想法。

在这十几年里面,有众多的世界级专家参与过这个问题的研究,包括程序语言领域的鼻祖之一,爱丁堡大学教授,英国皇家学会院士Gordon Plotkin,天才的丹麦Aarhus大学教授Olivier Danvy,CMU的Andrzej Filinski(现在DIKU),Indiana的Dan Friedman以及他的得意门生,天才的Matthias Felleisen,Felleisen的得意门生,天才的Amr Sabry(我的导师),普林斯顿大学教授Andrew Appel(编译器教材“虎书”的作者)。这些人为这个话题发表了不知道多少论文,Andrew Appel还为此专门写了一本书,叫做《Compiling with Continuations》。我之所以会去解决这个问题,是因为Friedman耍老顽童的花样,别出心裁地把这个问题作为了一道附加题目放进了B521的作业里。我不知道这个问题有如此之难,所以愣头愣脑,真把它当成作业题给解决了。按照作业的“道德规范”,完全从问题出发,不看书不看论文不查网络,全凭自己的头脑,在一个星期之内,把代码反反复复重写了几十次,最后得到了最优的结果。这就是所谓“王垠40行代码”的含义,虽然最后只剩下40行,然而却不知道删掉了多少。为了这40行代码,一个人七天,一群人十年,我想你应该知道这是什么概念。

当我最后把代码交给Dan Friedman的时候,他不相信我的代码是正确的,因为历史上有许多的学生声称做出了这道题目,然而他们几乎全都是错的,或者采用了效率很低的做法。只有深入到精髓,才会明白怎么写出这些代码。那么多大牛花了那么多年工夫才研究清楚,所以Friedman把这问题放在作业里面,其实根本就没指望有人能够解决。所以自然,他很难相信任何人能够做出这道题目。那天Friedman用惊讶又怀疑的眼神看着我,然后给了我一篇30多页的论文。这篇论文是历史上这个问题的一个重大突破,作者是他的好朋友,Danvy和Filinsky。可是这论文写得含混晦涩,所以我花了超过一个月才琢磨清楚这篇论文是怎么回事,我至今被那些公式弄得眼花缭乱。可是最后我发现,我的自己写出来的代码完全的实现了它最后的思想,而且还要更加优雅。所以当最后我在班上讲解这片代码是怎么回事的时候,Friedman对大家说:“你们可要听仔细了,这个值100美元!”

我的名字叫做王垠(父亲起名含义是谐音“亡垠”,无边无垠的意思),所以我将会永不停息的完善自己,永远不会拿某一个东西自居。解决这个难题只是对我这个人内在品质的一种反映而已,而且它只是我在B521做出的好几个“课外练习”的其中一个。在短短一学期的时间里,我还进行了其它几个重量级的练习,包括重新实现miniKanren语言,加入constraint logic programming功能和一种非常强大的逻辑逆(negation)操作符,等等。这些练习,全都是独立依靠自己领悟摸索完成,没有查阅任何书籍和论文资料。从这些练习里面,我获得了让我受益终生的独立思考能力。也就是这种能力,让我可以在Google,Coverity之类的公司,轻松解决其他人咋咋呼呼,认为不可能完成的任务。这就是为什么我会讲这个课程的故事,并且告诉你我得了A+。

有趣的是,学期结束的时候,成绩单上出现的分数其实是I(Incomplete)。这种成绩表示有课程任务没有完成,如果在一年之内不弥补,就会变成F(不及格)。我很纳闷,发信去问Friedman。他回答说:“对不起,是秘书搞错了!” 然后急忙发信给秘书说:“这个人的分数应该是A+!实际上如果可能的话,我希望给他A+++++++!”

现在你还觉得我是因为肤浅才告诉你这个A+分数吗?B521教会我的,是一生最重要的东西,它让我真正的理解了什么叫做“简单”,它使得我去追寻它。它赋予我的独立思考能力,继续在帮助我用巧妙简单的方法解决其他人望而却步的问题。这不是一个普通的A+,这是一个把我送上世界巅峰,给予我勇气和自由思想的A+。

就像爱因斯坦说的,任何一个傻瓜都可以把问题搞复杂,你需要一点天才,还有很多勇气,才能达到简单。很多牛人用“简单”来标榜自己设计的东西,然而我发现他们对简单的理解其实很肤浅。大部分时候他们用一种类似“皇帝的新装”的心理技巧——你如果不能理解他的东西,他就说你是傻瓜或者菜鸟,不能理解这种简单。所以没有人敢说他们设计的东西太复杂。

你觉得世界上有几个人能够在B521上得A+呢?谦虚是一种美德,不要随便评判别人,然而当看到这么多大牛都那么不谦虚,耀武扬威的,很多人用他们作为评判其他人的依据,所以我只好冒着评判他们的风险,告诉你一些事实。其实Donald Knuth, Dennis Ritchie, Bjarne Stroustrup, Guido van Rossum, Brendan Eich, Linus Torvalds, Rob Pike, ... 这些很多人仰慕的大牛,如果上B521肯定是连A都拿不到的。有些甚至不能及格,因为有些人根本不知道他们在干什么,设计出一堆复杂的垃圾,然后仗着自己的威望和强权迫使你去“学习”。其实我对计算机的理解跟这些大牛们,早就不在一个数量级上了。我心里有数他们该得什么分数,你们自己猜猜吧。

本来不想这么赤裸裸的跟人比较的,然而我发现我的话语权和我对事物的认识深度比起来,实在相差太多。当我说到一些事情的时候,经常有人抬出这些人的语录来压制,说得好像圣经似的,对我各种评判,所以觉得有必要特此说明一下。这些大牛在我心目中真的一点权威都没有的,我反而清楚他们肚子里到底有多少货,思维方式有哪些误区和局限性。

也许我现在可以毫不担心的告诉你了,我在Kent Dybvig的编译器课程上得的也是A+。Kent恐怕是世界上最厉害的编译器作者,他几乎从来不给人A+,而我恐怕是他20多年来最厉害的一个学生。我们做了一个Scheme编译器,它的难度和工作量,是C语言编译器的两倍以上。由于我喜欢别出心裁,不按他的写法,我的课堂编译器的某些方面,其实超越了他的Chez Scheme。比如,我的编译器曾一度生成比他更高效的X64机器指令。然而Kent很会背地里偷学武功,闷声发大财。据课程助教说,Kent有几次偷偷在我的代码上做“侦探工作”挺久…… 再加上他几十年深藏不露的经验,所以他现在恐怕仍然比我强 :)